import { useLocation } from "umi";
import type { API } from "@/types/api";
import FileTreeViewer from "./getEditorValue";
import { useNavigate } from "react-router-dom";
import React, { useState, useRef } from "react";
import Editor, { useMonaco, loader } from "@monaco-editor/react";
import { postFileChange, postLookFileContext } from "@/services/hosting/api";
import { Select, Button, Input, InputNumber, message, Spin } from "antd";

loader.config({ paths: { vs: "/monaco-editor/vs" } });

const CodeEditor: React.FC = () => {
    const [defaultCode, setDefaultCode] =
        useState<string>("请在左侧选择文件...");
    const location = useLocation();
    const params = new URLSearchParams(location.search);
    const appId: string = params.get("appId") || "";
    const stype: string = params.get("type") || "";
    const [resetButton, setResetButtom] = useState(false);
    const [code, setCode] = useState<string>("请在左侧选择文件...");
    const [language, setLanguage] = useState<string>("plaintext");
    const monaco = useMonaco();
    const editorRef = useRef<any>(null);
    const [fontSize, setFontSize] = useState<number>(14);
    const [fileName, setFileName] = useState<string>("");
    const [filePath, setFilePath] = useState<string>("");
    const [loading, setLoading] = useState(false);
    const nodeId = new URLSearchParams(window.location.search).get("nodeId") as string;
    const handleFontSizeWheel = (e: React.WheelEvent) => {
        const delta = e.deltaY > 0 ? -1 : 1;
        setFontSize(Math.max(1, Math.min(50, fontSize + delta)));
    };
    const navigate = useNavigate();
    const [hasCode, setHasCode] = useState(false);
    const codeContextGet = async (values: API.PostJarContext) => {
        setLoading(true);
        try {
            const res = (await postLookFileContext(
                { ...values },
                stype,
                nodeId,
                navigate,
            )) as API.PostJarContextResult;

            // 设置文件路径
            setFilePath(values.path);

            if (typeof res.message === "string") {
                message.error(res.message);
                setCode("加载文件内容失败");
            } else if (Array.isArray(res.message)) {
                const firstItem = res.message[0];
                if (firstItem.value === null) {
                    message.info("二进制文件无法加载！");
                    setCode("无法查看二进制文件！");
                } else {
                    setDefaultCode(firstItem.value);
                    setCode(firstItem.value);
                    setLanguage(firstItem.guess);
                }
            } else {
                if (res.message.value === null) {
                    message.info("二进制文件无法加载！");
                    setCode("无法查看二进制文件！");
                } else {
                    setDefaultCode(res.message.value);
                    setCode(res.message.value);
                    setLanguage(res.message.guess);
                    setHasCode(true);
                }
            }
        } catch (err) {
            console.error(err);
            message.error("加载文件内容失败");
        } finally {
            setLoading(false);
        }
    };

    const handleFind = () => {
        if (editorRef.current) {
            editorRef.current.focus();
            editorRef.current.trigger("", "actions.find", {});
        }
    };

    const saveCode = async () => {
        if (!filePath) {
            message.error("请先选择文件");
            return;
        }

        message.info("保存中...");
        try {
            const res = await postFileChange(
                {
                    app_id: appId,
                    path: filePath,
                    value: code,
                },
                stype,
                nodeId,
                navigate,
            );

            if (res) {
                message.success("保存成功");
                // 保存成功后更新默认代码
                setDefaultCode(code);
                setResetButtom(false);
            }
        } catch (error) {
            console.error("保存失败:", error);
            message.error("保存失败");
        }
    };

    const resetCode = () => {
        setCode(defaultCode);
        setResetButtom(false);
    };

    return (
        <div
            style={{
                height: "100%",
                display: "flex",
                flexDirection: "column",
                overflow: "hidden",
            }}
        >
            <div style={{ flex: 1, display: "flex", overflow: "hidden" }}>
                <div
                    style={{
                        width: "30%",
                        minWidth: 300,
                        maxWidth: 450,
                        background: "#fff",
                        display: "flex",
                        flexDirection: "column",
                        overflow: "hidden",
                    }}
                >
                    <div
                        style={{
                            flex: 1,
                            overflow: "auto",
                            marginTop: 10,
                            padding: "0",
                        }}
                    >
                        <FileTreeViewer
                            getCodeContent={codeContextGet}
                            setFileName={setFileName}
                            appId={appId}
                            stype={stype}
                            setFilePath={setFilePath}
                            loading={loading} // 传递 loading 状态
                        />
                    </div>
                </div>

                <div
                    style={{
                        flex: 1,
                        minWidth: 400,
                        display: "flex",
                        flexDirection: "column",
                        overflow: "hidden",
                        position: "relative",
                    }}
                >
                    {loading && (
                        <div
                            style={{
                                position: "absolute",
                                top: 0,
                                left: 0,
                                right: 0,
                                bottom: 0,
                                backgroundColor: "rgba(0,0,0,0.1)",
                                zIndex: 100,
                                display: "flex",
                                justifyContent: "center",
                                alignItems: "center",
                            }}
                        >
                            <Spin size="large" tip="加载文件内容中..." />
                        </div>
                    )}
                    <div
                        style={{
                            flex: 1,
                            display: "flex",
                            flexDirection: "column",
                            overflow: "hidden",
                        }}
                    >
                        <div
                            style={{
                                padding: "10px 16px",
                                background: "#fff",
                                display: "flex",
                                justifyContent: "space-between",
                                alignItems: "center",
                                // borderBottom: "1px solid #f0f0f0",
                                flexWrap: "wrap",
                                gap: 16,
                            }}
                        >
                            <div
                                style={{
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 16,
                                }}
                            >
                                <div
                                    style={{
                                        display: "flex",
                                        alignItems: "center",
                                        gap: 8,
                                    }}
                                >
                                    <span>语言模式：</span>
                                    <Select
                                        showSearch
                                        value={language}
                                        style={{ width: 120 }}
                                        options={[
                                            {
                                                value: "plaintext",
                                                label: "Plain Text",
                                            },
                                            {
                                                value: "javascript",
                                                label: "JavaScript",
                                            },
                                            // {
                                            //     value: "typescript",
                                            //     label: "TypeScript",
                                            // },
                                            { value: "html", label: "HTML" },
                                            { value: "css", label: "CSS" },
                                            { value: "json", label: "JSON" },
                                            {
                                                value: "python",
                                                label: "Python",
                                            },
                                            { value: "java", label: "Java" },
                                            { value: "xml", label: "XML" },
                                            { value: "yaml", label: "YAML" },
                                            // {
                                            //     value: "markdown",
                                            //     label: "Markdown",
                                            // },
                                            { value: "sql", label: "SQL" },
                                            {
                                                value: "shell",
                                                label: "Shell Script",
                                            },
                                        ]}
                                        onChange={(e) => setLanguage(e)}
                                    />
                                </div>

                                <div
                                    style={{
                                        display: "flex",
                                        alignItems: "center",
                                        gap: 8,
                                    }}
                                >
                                    <span>字体大小：</span>
                                    <InputNumber
                                        min={1}
                                        max={50}
                                        value={fontSize}
                                        onWheel={handleFontSizeWheel}
                                        onChange={(newValue) =>
                                            setFontSize(newValue || 1)
                                        }
                                    />
                                </div>
                                <div
                                    style={{
                                        display: "flex",
                                        alignItems: "center",
                                        gap: 8,
                                    }}
                                >
                                    <span style={{ minWidth: "60px" }}>
                                        文件名：
                                    </span>
                                    <Input
                                        readOnly
                                        value={fileName}
                                        onChange={(e) =>
                                            setFileName(e.target.value)
                                        }
                                        style={{ width: 500 }}
                                    />
                                </div>
                            </div>

                            <div
                                style={{
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 8,
                                }}
                            >
                                <Button onClick={handleFind}>查找</Button>
                                <Button
                                    disabled={!resetButton}
                                    onClick={resetCode}
                                >
                                    重置
                                </Button>
                                <Button
                                    disabled={!resetButton}
                                    type="primary"
                                    ghost
                                    onClick={saveCode}
                                >
                                    保存
                                </Button>
                            </div>
                        </div>

                        <div
                            style={{
                                flex: 1,
                                overflow: "hidden",
                                borderRadius: "10px",
                                border: "1px solid #f0f0f0",
                            }}
                        >
                            <Editor
                                height="98%"
                                language={language}
                                theme="light"
                                value={code}
                                onChange={(value) => {
                                    if (value !== defaultCode)
                                        setResetButtom(true);
                                    setCode(value || "");
                                }}
                                onMount={(editor) => {
                                    editorRef.current = editor;
                                }}
                                options={{
                                    minimap: { enabled: false }, // 禁用缩略图
                                    quickSuggestions: false, // 禁用快速建议
                                    smoothScrolling: false, // 禁用平滑滚动
                                    cursorSmoothCaretAnimation: "off", // 禁用光标动画
                                    fontSize: fontSize,
                                    wordWrap: "on",
                                    automaticLayout: true,
                                    scrollBeyondLastLine: false,
                                    renderWhitespace: "selection",
                                    tabSize: 4,
                                    formatOnPaste: true,
                                    formatOnType: true,
                                }}
                            />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default CodeEditor;
